import express, { Request, Response } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import compression from 'compression';
import rateLimit from 'express-rate-limit';
import swaggerJsdoc from 'swagger-jsdoc';
import swaggerUi from 'swagger-ui-express';
import path from 'path';

import { errorHandler } from './middleware/errorHandler';
import { notFoundHandler } from './middleware/notFoundHandler';
import { languageDetector, languageInfo } from './middleware/languageDetector';
import { operationLogMiddleware } from './middleware/operationLog';
import { logger } from './utils/logger';
import { connectDatabase } from './config/database';
import { ConfigUtils, initializeConfig } from './config';
import { configureRoutes, getRouteInfo } from './routes/router';

// CSP配置函数
function getCSPHeaders() {
  return {
    'Content-Security-Policy': [
      "default-src 'self' http: https:;",
      "script-src 'self' 'unsafe-inline' http: https:;",
      "style-src 'self' 'unsafe-inline' http: https:;",
      "img-src 'self' data: http: https: blob: *;",  // 允许所有来源的图片
      "font-src 'self' data: http: https:;",
      "connect-src 'self' http: https:;",
      "media-src 'self' http: https:;",
      "object-src 'none';",
      "base-uri 'self';",
      "form-action 'self';"
    ].join(' '),
    'X-Content-Type-Options': 'nosniff',
    'X-Frame-Options': 'DENY',
    'X-XSS-Protection': '1; mode=block'
  };
}

// 初始化配置
const appConfig = initializeConfig();

const app = express();
const PORT = appConfig.server.port;
// 生产环境代理设置
if (process.env.NODE_ENV === 'production') {
  // 信任所有代理（适用于 Nginx 反向代理）
  app.set('trust proxy', true);
  
  // 或者更安全的设置
  // app.set('trust proxy', 'loopback, linklocal, uniquelocal');
} else {
  // 开发环境
  app.set('trust proxy', 'loopback');
}

// 安全中间件
app.use(helmet());

// 全局CORS配置 - 必须在所有路由之前
app.use((req, res, next) => {
  // 为所有请求添加CORS头
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Expose-Headers', 'Content-Length, X-Requested-With');
  res.header('Cross-Origin-Resource-Policy', "cross-origin");
  
  // 处理预检请求
  if (req.method === 'OPTIONS') {
    res.header('Access-Control-Max-Age', '86400'); // 24小时
    res.sendStatus(200);
    return;
  }
  
  next();
});

// 跨域配置
app.use(cors({
  origin: '*', // 允许所有来源
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
  exposedHeaders: ['Content-Length', 'X-Requested-With']
}));

// 专门为图片资源添加CORS头（作为备用）
app.use('/uploads', (_req, res, next) => {
  // Nginx已经处理了CORS，这里作为备用
  res.header('Cache-Control', 'public, max-age=86400'); // 1天缓存
  next();
});

// 为所有静态资源添加CORS头
app.use((req, res, next) => {
  // 如果是图片、字体等静态资源请求，添加CORS头
  if (req.path.match(/\.(png|jpg|jpeg|gif|ico|svg|webp|bmp|tiff|woff|woff2|ttf|eot)$/)) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    res.header('Access-Control-Allow-Credentials', 'true');
  }
  next();
});

// 请求限流
const limiter = rateLimit({
  windowMs: ConfigUtils.getRateLimitConfig().windowMs,
  max: ConfigUtils.getRateLimitConfig().max,
  message: {
    error: '请求过于频繁，请稍后再试'
  }
});
app.use('/api/', limiter);

// 压缩响应
app.use(compression());

// 日志中间件
app.use(morgan('combined', {
  stream: {
    write: (message: string) => logger.info(message.trim())
  }
}));

// 语言检测中间件
app.use(languageDetector);
app.use(languageInfo);

// 操作日志中间件
app.use(operationLogMiddleware);

// 解析请求体
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

// Swagger API文档配置
const swaggerOptions:swaggerJsdoc.Options = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'OffGrid API',
      version: '1.0.0',
      description: 'OffGrid音乐节助手API文档',
      contact: {
        name: 'API Support',
        email: 'support@offgrid.com'
      }
    },
    servers: [
      {
        url: `http://${appConfig.server.host}:${PORT}`,
        description: '开发服务器'
      }
    ],
    components: {
      securitySchemes: {
        bearerAuth: {
          type: 'http',
          scheme: 'bearer',
          bearerFormat: 'JWT'
        }
      }
    },
    security: [
      {
        bearerAuth: []
      }
    ]
  },
  apis: [
    './src/routes/**/*.ts',
    './src/admin/routes/**/*.ts'
  ]
};

const swaggerSpec:swaggerJsdoc.Options = swaggerJsdoc(swaggerOptions);

// API文档路由（仅在开发环境或明确启用时显示）
if (ConfigUtils.isSwaggerEnabled()) {
  // 添加中间件确保整个 /api-docs/ 目录都使用 HTTP 协议  
  // 添加通用静态资源处理中间件，确保所有资源都使用 HTTP
  app.use('/api-docs', (_req, res, next) => {
    // 设置响应头，强制使用 HTTP 协议
    res.setHeader('Content-Security-Policy', "default-src 'self' http: https:; script-src 'self' 'unsafe-inline' http: https:; style-src 'self' 'unsafe-inline' http: https:; img-src 'self' data: http: https:;");
    next();
  });
  app.use(ConfigUtils.getSwaggerPath(), swaggerUi.serve, swaggerUi.setup(swaggerSpec));
  logger.info(`📚 Swagger 文档已启用: http://${appConfig.server.host}:${PORT}${ConfigUtils.getSwaggerPath()}`);
}

// 健康检查
app.get('/health', (_req: Request, res: Response) => {
  res.json({
    status: 'OK',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    environment: appConfig.server.environment
  });
});

// 图片CORS测试路由
app.get('/test-cors', (_req: Request, res: Response) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  
  res.json({
    message: 'CORS配置正常',
    timestamp: new Date().toISOString(),
    cors: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, OPTIONS',
      'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
      'Access-Control-Allow-Credentials': 'true'
    }
  });
});

// 静态文件服务
app.use('/uploads', express.static(path.join(__dirname, '../uploads'), {
  setHeaders: (res, path) => {
    // 使用统一的CSP配置
    Object.entries(getCSPHeaders()).forEach(([key, value]) => {
      res.setHeader(key, value);
    });
    
    // 为图片资源添加缓存头（CORS由Nginx处理）
    if (path.match(/\.(png|jpg|jpeg|gif|ico|svg|webp|bmp|tiff)$/)) {
      res.setHeader('Cache-Control', 'public, max-age=86400'); // 1天缓存
    }
  }
}));

// 配置API路由（最高优先级，优先于静态文件服务）
const apiRouter = configureRoutes();
app.use('/', apiRouter);

// 后台管理静态文件服务（/admin/* 路由到 public/admin 目录）
app.use('/admin', express.static(path.join(__dirname, '../public/admin'), {
  maxAge: '1d', // 缓存1天
  etag: true,
  lastModified: true,
  setHeaders: (res, path) => {
    // 使用统一的CSP配置
    Object.entries(getCSPHeaders()).forEach(([key, value]) => {
      res.setHeader(key, value);
    });
    
    // 为图片资源添加CORS头
    if (path.match(/\.(png|jpg|jpeg|gif|ico|svg|webp|bmp|tiff)$/)) {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
      res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }
    
    // 为HTML文件设置不缓存
    if (path.endsWith('.html')) {
      res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
      res.setHeader('Pragma', 'no-cache');
      res.setHeader('Expires', '0');
    }
    // 为静态资源设置缓存
    else if (path.match(/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/)) {
      res.setHeader('Cache-Control', 'public, max-age=86400'); // 1天
    }
  }
}));

// 前端客户端应用静态文件服务（根路径 / 路由到 public 目录）
app.use('/', express.static(path.join(__dirname, '../public'), {
  maxAge: '1d', // 缓存1天
  etag: true,
  lastModified: true,
  setHeaders: (res, path) => {
    // 使用统一的CSP配置
    Object.entries(getCSPHeaders()).forEach(([key, value]) => {
      res.setHeader(key, value);
    });
    
    // 为图片资源添加CORS头
    if (path.match(/\.(png|jpg|jpeg|gif|ico|svg|webp|bmp|tiff)$/)) {
      res.setHeader('Access-Control-Allow-Origin', '*');
      res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
      res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    }
    
    // 为HTML文件设置不缓存
    if (path.endsWith('.html')) {
      res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
      res.setHeader('Pragma', 'no-cache');
      res.setHeader('Expires', '0');
    }
    // 为静态资源设置缓存
    else if (path.match(/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/)) {
      res.setHeader('Cache-Control', 'public, max-age=86400'); // 1天
    }
  }
}));

// 处理后台管理页面的SPA路由（/admin/* 所有未匹配的路由都返回 admin/index.html）
app.get('/admin/*', (_req, res) => {
  // 使用统一的CSP配置
  Object.entries(getCSPHeaders()).forEach(([key, value]) => {
    res.setHeader(key, value);
  });
  
  const indexPath = path.join(__dirname, '../public/admin/index.html');
  res.sendFile(indexPath, (err) => {
    if (err) {
      logger.error('后台管理页面文件不存在:', indexPath);
      res.status(404).json({
        success: false,
        code: 404,
        message: '后台管理页面不存在',
        timestamp: new Date().toISOString()
      });
    }
  });
});

// 处理前端客户端应用的SPA路由（根路径 /* 所有未匹配的路由都返回 index.html）
app.get('*', (req, res, next) => {
  // 跳过API路由、admin路由、uploads、health检查等
  if (req.path.startsWith('/api/') || req.path.startsWith('/admin/') || 
      req.path.startsWith('/uploads/') || req.path.startsWith('/health') || 
      req.path.startsWith('/api-docs')) {
    return next();
  }
  
  // 使用统一的CSP配置
  Object.entries(getCSPHeaders()).forEach(([key, value]) => {
    res.setHeader(key, value);
  });
  
  const indexPath = path.join(__dirname, '../public/index.html');
  res.sendFile(indexPath, (err) => {
    if (err) {
      logger.error('前端客户端页面文件不存在:', indexPath);
      res.status(404).json({
        success: false,
        code: 404,
        message: '前端客户端页面不存在',
        timestamp: new Date().toISOString()
      });
    }
  });
});

// 404处理
app.use(notFoundHandler);

// 错误处理中间件
app.use(errorHandler);

// 启动服务器
async function startServer() {
  try {
    // 验证配置
    const validation = ConfigUtils.validateConfig();
    if (!validation.isValid) {
      logger.error('配置验证失败:', validation.errors);
      process.exit(1);
    }

    // 记录配置摘要
    logger.info('应用配置:', ConfigUtils.getSafeConfig());

    // 检查静态文件目录
    const publicDir = path.join(__dirname, '../public');
    const fs = require('fs');
    if (!fs.existsSync(publicDir)) {
      logger.warn('前端客户端静态文件目录不存在:', publicDir);
      logger.info('请确保已构建前端客户端项目并放置在 public/ 目录中');
    } else {
      logger.info('✅ 前端客户端静态文件目录已就绪:', publicDir);
    }

    // 检查后台管理静态文件目录
    const adminDir = path.join(__dirname, '../public/admin');
    if (!fs.existsSync(adminDir)) {
      logger.warn('后台管理静态文件目录不存在:', adminDir);
      logger.info('请确保已构建后台管理前端项目并放置在 public/admin/ 目录中');
    } else {
      logger.info('✅ 后台管理静态文件目录已就绪:', adminDir);
    }

    // 连接数据库
    await connectDatabase();
    logger.info('数据库连接成功');

    // 启动服务器
    app.listen(PORT, appConfig.server.host, () => {
      logger.info(`🚀 服务器启动成功！`);
      logger.info(`📍 运行环境: ${appConfig.server.environment}`);
      logger.info(`🌐 服务器地址: http://${appConfig.server.host}:${PORT}`);
      logger.info(`📚 API文档地址: http://${appConfig.server.host}:${PORT}/api-docs`);
      logger.info(`⚙️ 后台管理地址: http://${appConfig.server.host}:${PORT}/admin`);
      logger.info(`📱 前端客户端地址: http://${appConfig.server.host}:${PORT}/`);
      logger.info(`💚 健康检查地址: http://${appConfig.server.host}:${PORT}/health`);
      // 显示路由信息
      const routeInfo = getRouteInfo();
      logger.info('📱 客户端API路由:', routeInfo.client);
      logger.info('⚙️ 管理后台API路由:', routeInfo.admin);
      logger.info('🔄 兼容性API路由:', routeInfo.compatibility);
      
      if (ConfigUtils.isDevelopment()) {
        logger.info('🔧 开发模式已启用');
      }
    });
  } catch (error) {
    logger.error('服务器启动失败:', error);
    process.exit(1);
  }
}

// 优雅关闭
process.on('SIGTERM', () => {
  logger.info('收到 SIGTERM 信号，正在关闭服务器...');
  process.exit(0);
});

process.on('SIGINT', () => {
  logger.info('收到 SIGINT 信号，正在关闭服务器...');
  process.exit(0);
});

// 启动服务器
startServer();

export default app; 